home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 2.1 / Amiga Developer CD v2.1.iso / Extras / BOOPSI / led_ic / dispatch.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-10-27  |  8.7 KB  |  375 lines

  1. /* led image
  2.  * Copyright (c) 1994-1999 Amiga, Inc.
  3.  * Written by David N. Junod
  4.  *
  5.  */
  6.  
  7. /*****************************************************************************/
  8.  
  9. #define    DB(x)    ;
  10.  
  11. /*****************************************************************************/
  12.  
  13. #include <exec/types.h>
  14. #include <intuition/intuition.h>
  15. #include <intuition/imageclass.h>
  16. #include <intuition/classusr.h>
  17. #include <intuition/classes.h>
  18. #include <intuition/cghooks.h>
  19. #include <graphics/displayinfo.h>
  20. #include <graphics/gfxmacros.h>
  21. #include <images/led.h>
  22. #include <string.h>
  23.  
  24. #include <clib/exec_protos.h>
  25. #include <clib/graphics_protos.h>
  26. #include <clib/intuition_protos.h>
  27. #include <clib/utility_protos.h>
  28. #include <clib/macros.h>
  29.  
  30. #include <pragmas/exec_pragmas.h>
  31. #include <pragmas/graphics_pragmas.h>
  32. #include <pragmas/intuition_pragmas.h>
  33. #include <pragmas/utility_pragmas.h>
  34.  
  35. #include "classbase.h"
  36. #include "classdata.h"
  37.  
  38. /*****************************************************************************/
  39.  
  40. static char SegmentArray[11][7] =
  41. {
  42.     {1, 1, 1, 1, 1, 1, 0},
  43.     {0, 1, 1, 0, 0, 0, 0},
  44.     {1, 1, 0, 1, 1, 0, 1},
  45.     {1, 1, 1, 1, 0, 0, 1},
  46.     {0, 1, 1, 0, 0, 1, 1},
  47.     {1, 0, 1, 1, 0, 1, 1},
  48.     {1, 0, 1, 1, 1, 1, 1},
  49.     {1, 1, 1, 0, 0, 0, 0},
  50.     {1, 1, 1, 1, 1, 1, 1},
  51.     {1, 1, 1, 0, 0, 1, 1},
  52.     {0, 0, 0, 0, 0, 0, 0}
  53. };
  54.  
  55. /*****************************************************************************/
  56.  
  57. static LONG setAttrsMethod (Class * cl, struct Image * im, struct opSet * msg, BOOL init)
  58. {
  59.     struct ClassLib *cb = (struct ClassLib *) cl->cl_UserData;
  60.     struct objectData *od = INST_DATA (cl, im);
  61.     struct TagItem *tags = msg->ops_AttrList;
  62.     LONG segs, time, refresh;
  63.     struct TagItem *tstate;
  64.     struct TagItem *tag;
  65.     ULONG tidata;
  66.  
  67.     /* Initialize the variables */
  68.     if (init)
  69.     {
  70.     im->Width = im->Height = 40;
  71.     segs = time = refresh = 1;
  72.     od->od_Pairs = 2;
  73.     }
  74.     else
  75.     {
  76.     /* Let the super class handle it first */
  77.     segs = time = 0;
  78.     refresh = DoSuperMethodA (cl, (Object *) im, msg);
  79.     }
  80.  
  81.     /* process rest */
  82.     tstate = tags;
  83.     while (tag = NextTagItem (&tstate))
  84.     {
  85.     tidata = tag->ti_Data;
  86.     switch (tag->ti_Tag)
  87.     {
  88.         case LED_Pairs:
  89.         od->od_Pairs = (WORD) tidata;
  90.         time = refresh = 1;
  91.         break;
  92.  
  93.         case LED_Values:
  94.         /* Copy the values into our array */
  95.         CopyMem ((APTR)tidata, (APTR)od->od_Values, sizeof (WORD) * od->od_Pairs);
  96.         time = refresh = 1;
  97.         break;
  98.  
  99.         case LED_Colon:
  100.         if (tidata)
  101.             od->od_Flags |= ODF_COLON;
  102.         else
  103.             od->od_Flags &= ~ODF_COLON;
  104.         break;
  105.  
  106.         case LED_Negative:
  107.         if (tidata)
  108.             od->od_Flags |= ODF_NEGATIVE;
  109.         else
  110.             od->od_Flags &= ~ODF_NEGATIVE;
  111.         refresh = 1;
  112.         break;
  113.  
  114.         case LED_Signed:
  115.         if (tidata)
  116.             od->od_Flags |= ODF_SIGNED;
  117.         else
  118.             od->od_Flags &= ~ODF_SIGNED;
  119.         segs = refresh = 1;
  120.         break;
  121.  
  122.         case SYSIA_DrawInfo:
  123.         od->od_DrawInfo = (struct DrawInfo *) tidata;
  124.         break;
  125.  
  126.         case IA_BGPen:
  127.         od->od_BackgroundPen = tidata;
  128.         refresh = 1;
  129.         break;
  130.  
  131.         case IA_FGPen:
  132.         od->od_TextPen = tidata;
  133.         refresh = 1;
  134.         break;
  135.  
  136.         case IA_Width:
  137.         im->Width = (WORD) tidata;
  138.         segs = refresh = 1;
  139.         break;
  140.  
  141.         case IA_Height:
  142.         im->Height = (WORD) tidata;
  143.         segs = refresh = 1;
  144.         break;
  145.     }
  146.     }
  147.  
  148.     /* Make sure we have valid pens */
  149.     if (od->od_BackgroundPen == -1)
  150.     od->od_BackgroundPen = (LONG)od->od_DrawInfo->dri_Pens[BACKGROUNDPEN];
  151.     if (od->od_TextPen == -1)
  152.     od->od_TextPen = (LONG)od->od_DrawInfo->dri_Pens[TEXTPEN];
  153.  
  154.     /* Recalculate segment positioning */
  155.     if (segs)
  156.     {
  157.     struct Rectangle *r;    /* Current rectangle */
  158.     WORD hsw;        /* Horizontal segment width */
  159.     WORD hsh;        /* Horizontal segment height */
  160.     WORD vsw;        /* Vertical segment width */
  161.     WORD vsh;        /* Vertical segment height */
  162.     WORD ho;        /* Horizontal offset */
  163.     WORD vo;        /* Vertical offset */
  164.  
  165.     /* Calculate segment sizes */
  166.     ho = ((6 + 2 + 6) * od->od_Pairs) + ((od->od_Pairs - 1) * 5);
  167.     if (od->od_Flags & ODF_SIGNED)
  168.         ho += 5;
  169.     od->od_VCell = im->Height / 12;
  170.     od->od_HCell = im->Width / ho;
  171.     hsw = od->od_HCell * 6;
  172.     vsh = im->Height / 2; // od->od_VCell * 6;
  173.     vo = hsh = od->od_VCell;
  174.     ho = vsw = od->od_HCell;
  175.     od->od_HSW = hsw;
  176.     od->od_VSW = vsw;
  177.  
  178.     /* 0 - horizontal */
  179.     r = &od->od_Segments[0];
  180.     r->MinX = ho;
  181.     r->MinY = 0;
  182.     r->MaxX = hsw - ho - 1;
  183.     r->MaxY = r->MinY + od->od_VCell - 1;
  184.  
  185.     /* 1 - vertical */
  186.     r = &od->od_Segments[1];
  187.     r->MinX = hsw - ho;
  188.     r->MinY = vo;
  189.     r->MaxX = hsw - 1;
  190.     r->MaxY = vsh - vo;
  191.  
  192.     /* 2 - vertical */
  193.     r = &od->od_Segments[2];
  194.     r->MinX = hsw - ho;
  195.     r->MinY = vsh + 1;
  196.     r->MaxX = hsw - 1;
  197.     r->MaxY = im->Height - vo - 1;
  198.  
  199.     /* 3 - horizontal */
  200.     r = &od->od_Segments[3];
  201.     r->MinX = ho;
  202.     r->MinY = im->Height - od->od_VCell;
  203.     r->MaxX = hsw - ho - 1;
  204.     r->MaxY = r->MinY + od->od_VCell - 1;
  205.  
  206.     /* 4 - vertical */
  207.     r = &od->od_Segments[4];
  208.     r->MinX = 0;
  209.     r->MinY = vsh + 1;
  210.     r->MaxX = ho - 1;
  211.     r->MaxY = im->Height - vo - 1;
  212.  
  213.     /* 5 - vertical */
  214.     r = &od->od_Segments[5];
  215.     r->MinX = 0;
  216.     r->MinY = vo;
  217.     r->MaxX = ho - 1;
  218.     r->MaxY = vsh - vo;
  219.  
  220.     /* 6 - horizontal */
  221.     r = &od->od_Segments[6];
  222.     r->MinX = ho;
  223.     r->MinY = vsh - od->od_VCell + 1;
  224.     r->MaxX = hsw - ho - 1;
  225.     r->MaxY = r->MinY + od->od_VCell - 1;
  226.  
  227.     /* 7 - top colon */
  228.     r = &od->od_Segments[7];
  229.     r->MinX = 0;
  230.     r->MinY = (od->od_VCell * 3) - 1;
  231.     r->MaxX = ho - 1;
  232.     r->MaxY = r->MinY + od->od_VCell;
  233.  
  234.     /* 8 - bottom colon */
  235.     r = &od->od_Segments[8];
  236.     r->MinX = 0;
  237.     r->MinY = (od->od_VCell * 9) - 1;
  238.     r->MaxX = ho - 1;
  239.     r->MaxY = r->MinY + od->od_VCell;
  240.  
  241.     /* 9 - negative */
  242.     r = &od->od_Segments[9];
  243.     r->MinX = 0;
  244.     r->MinY = vsh - vo + 1;
  245.     r->MaxX = (od->od_HCell * 3) - 1;
  246.     r->MaxY = r->MinY + od->od_VCell - 1;
  247.     }
  248.  
  249.     /* If the time changed, then we need to fill in the lit segment array */
  250.     if (time)
  251.     {
  252.     UBYTE i, j, k;
  253.     WORD digit;
  254.  
  255.     for (i = k = 0; i < 8; i++)
  256.     {
  257.         digit = od->od_Values[i] / 10;
  258.         digit = (digit < 0 || digit > 9) ? 0 : digit;
  259.         for (j = 0; j < 7; j++)
  260.         od->od_LitSegments[k][j] = SegmentArray[digit][j];
  261.         k++;
  262.  
  263.         digit = od->od_Values[i] % 10;
  264.         digit = (digit < 0 || digit > 9) ? 0 : digit;
  265.         for (j = 0; j < 7; j++)
  266.         od->od_LitSegments[k][j] = SegmentArray[digit][j];
  267.         k++;
  268.     }
  269.     }
  270.  
  271.     return (refresh);
  272. }
  273.  
  274. /*****************************************************************************/
  275.  
  276. static LONG drawMethod (Class * cl, struct Image * im, struct impDraw * msg)
  277. {
  278.     struct ClassLib *cb = (struct ClassLib *) cl->cl_UserData;
  279.     struct objectData *od = INST_DATA (cl, im);
  280.     struct RastPort *rp;
  281.     struct Rectangle *r;
  282.     WORD i, j, k;
  283.     LONG tx, ty;
  284.     UBYTE bpen;
  285.  
  286.     /* Get the things that we need */
  287.     rp = msg->imp_RPort;
  288.  
  289.     /* Compute the size */
  290.     tx = (LONG) msg->imp_Offset.X;
  291.     ty = (LONG) msg->imp_Offset.Y;
  292.  
  293.     /* Get the background pen */
  294.     bpen = rp->BgPen; // od->od_BackgroundPen;
  295.  
  296.     /* Draw the sign */
  297.     if (od->od_Flags & ODF_SIGNED)
  298.     {
  299.     if (od->od_Flags & ODF_NEGATIVE)
  300.         SetAPen (rp, od->od_TextPen);
  301.     else
  302.         SetAPen (rp, bpen);
  303.     r = &od->od_Segments[9];
  304.     RectFill (rp, tx + (LONG)r->MinX, ty + (LONG)r->MinY, tx + (LONG)r->MaxX, ty + (LONG)r->MaxY);
  305.     tx += (od->od_HCell * 5);
  306.     }
  307.  
  308.     /* Draw Segments */
  309.     for (i = 0, k = od->od_Pairs << 1; i < k; i++)
  310.     {
  311.     for (j = 0; j < 7; j++)
  312.     {
  313.         if (od->od_LitSegments[i][j])
  314.         SetAPen (rp, od->od_TextPen);
  315.         else
  316.         SetAPen (rp, bpen);
  317.         r = &od->od_Segments[j];
  318.         RectFill (rp, tx + (LONG)r->MinX, ty + (LONG)r->MinY, tx + (LONG)r->MaxX, ty + (LONG)r->MaxY);
  319.     }
  320.  
  321.     tx += od->od_HSW + (od->od_HCell << 1);
  322.     if ((i & 1) && (i < k - 1))
  323.     {
  324.         if (od->od_Flags & ODF_COLON)
  325.         SetAPen (rp, od->od_TextPen);
  326.         else
  327.         SetAPen (rp, bpen);
  328.         r = &od->od_Segments[7];
  329.         RectFill (rp, tx + (LONG)r->MinX, ty + (LONG)r->MinY, tx + (LONG)r->MaxX, ty + (LONG)r->MaxY);
  330.         r = &od->od_Segments[8];
  331.         RectFill (rp, tx + (LONG)r->MinX, ty + (LONG)r->MinY, tx + (LONG)r->MaxX, ty + (LONG)r->MaxY);
  332.         tx += od->od_HCell + od->od_HCell + od->od_HCell;
  333.     }
  334.     }
  335.  
  336.     return (0);
  337. }
  338.  
  339. /*****************************************************************************/
  340.  
  341. static LONG newMethod (Class * cl, struct Image * im, struct opSet * msg)
  342. {
  343.     struct Image *newobj;
  344.  
  345.     /* Create the new object */
  346.     if (newobj = (struct Image *) DoSuperMethodA (cl, (Object *) im, msg))
  347.     {
  348.     /* Update the attributes */
  349.     setAttrsMethod (cl, newobj, msg, TRUE);
  350.     }
  351.  
  352.     return ((LONG) newobj);
  353. }
  354.  
  355. /*****************************************************************************/
  356.  
  357. LONG ASM ClassDispatcher (REG (a0) Class * cl, REG (a1) ULONG * msg, REG (a2) struct Image * im)
  358. {
  359.     switch (*msg)
  360.     {
  361.     case OM_NEW:
  362.         return newMethod (cl, im, (struct opSet *) msg);
  363.  
  364.     case OM_SET:
  365.     case OM_UPDATE:
  366.         return setAttrsMethod (cl, im, (struct opSet *) msg, FALSE);
  367.  
  368.     case IM_DRAW:
  369.         return drawMethod (cl, im, (struct impDraw *) msg);
  370.  
  371.     default:
  372.         return DoSuperMethodA (cl, (Object *) im, (Msg *) msg);
  373.     }
  374. }
  375.